package com.jsecode.lib.lang;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 有界hashmap的封装
 * @author grind
 *
 */
public class QueueMapImpl extends LinkedHashMap<Object, Object> {
    
    // 因为LRUMap在读的时候也有写操作,所以不使用ReadWriteLock
    private final ReentrantLock lock = new ReentrantLock();
    
    private final int maxSize;
    
    /**
     * 构造函数
     * 
     * @param initCapacity
     *            int 此map的初始化大小
     * @param maxSize
     *            int 此map最大容量，如map插入的数值超过此大小，最早被访问的元素将会被抛弃
     */
    public QueueMapImpl(int initCapacity, int maxSize) {
        super(initCapacity, 0.75f, true);
        this.maxSize = maxSize;
    }
    
    /**
     * @param maxSize
     *            此map的最大容量，初始大小为最大容量的1/4
     */
    public QueueMapImpl(int maxSize) {
        super(maxSize >> 2, 0.75f, true);
        this.maxSize = maxSize;
    }
    
    /**
     * 删除
     */
    protected boolean removeEldestEntry(Map.Entry<Object, Object> eldest) {
        return this.size() >= maxSize;
    }
    
    /*
     * (non-Javadoc)
     * @see java.util.LinkedHashMap#get(java.lang.Object)
     */
    @Override
    public Object get(Object key) {
        try {
            lock.lock();
            return super.get(key);
        } finally {
            lock.unlock();
        }
    }
    
    /*
     * (non-Javadoc)
     * @see java.util.HashMap#put(java.lang.Object, java.lang.Object)
     */
    @Override
    public Object put(Object key, Object val) {
        try {
            lock.lock();
            return super.put(key, val);
        } finally {
            lock.unlock();
        }
    }
    
    public static void main(String[] args) {
        QueueMapImpl map = new QueueMapImpl(4);
        map.put(1, 1);
        map.put(2, 2);
        map.put(3, 3);
        map.put(4, 4);
        map.remove(4);
        map.put(3, 32);
        map.put(5, 5);
        System.out.println(map);
        Iterator<Map.Entry<Object,Object>> ite = map.entrySet().iterator();
        while(ite.hasNext()){
            int str = (Integer)ite.next().getKey();
            if(str==3){
                map.put(7, 7);
            }
        }
        System.out.println(map);
        
    }
}